# -*- coding: utf-8 -*-
# =============================================================================
#     FileName: args_demo.py
#         Desc:
#       Author: GGA
#        Email:
#     HomePage:
#      Version: 1.0.1
#   LastChange: 2020-12-20
#      History:
# =============================================================================
import argparse
import os
import sys
import traceback

from utils.config_helper import TaskConfig, BaseConfig
from utils.log_helper import LogHelper
from utils.mysql_archiver import MyArchiver, MyArchiveType

logger = LogHelper.get_logger()


def get_parser():
    parser = argparse.ArgumentParser(
        description='Parse MySQL binlog to SQL you want',
        add_help=False)
    connect_setting = parser.add_argument_group('connect setting')
    parser.add_argument(
        '--help',
        dest='help',
        action='store_true',
        help='help information',
        default=False
    )
    connect_setting.add_argument(
        '--config_file',
        dest='config_file',
        type=str,
        default=None,
        help='the file path which contain host info'
    )
    return parser


def parse_args(command_args):
    need_print_help = False if command_args else True
    parser = get_parser()
    args = parser.parse_args(command_args)
    if args.help or need_print_help:
        parser.print_help()
        sys.exit(1)
    if args.config_file is None:
        logger.warning("parameter config_file must input")
        parser.print_help()
    return args


def check_config(base_config: BaseConfig, task_config: TaskConfig):
    source_server = base_config.source_server
    target_server = base_config.target_server
    if task_config.task_type == MyArchiveType.MYSQL_LOOP_DELETE:
        if task_config.target_table_name is not None:
            logger.warning("任务{}的类型配置为{},但目标表不为空，配置有误，请检查".format(
                task_config.task_name, "MYSQL_LOOP_DELETE"
            ))
            return False
    if task_config.task_type == MyArchiveType.MYSQL_LOOP_ARCHIVE:
        if target_server is None:
            logger.warning("任务{}的类型配置为{},但目标实例为空，配置有误，请检查".format(
                task_config.task_name, "MYSQL_LOOP_ARCHIVE"
            ))
            return False
    if task_config.task_type == MyArchiveType.MYSQL_LOOP_COPY:
        if target_server is None:
            logger.warning("任务{}的类型配置为{},但目标实例为空，配置有误，请检查".format(
                task_config.task_name, "MYSQL_LOOP_COPY"
            ))
            return False
    if target_server is not None:
        if source_server.mysql_host == target_server.mysql_host \
                and source_server.mysql_port == target_server.mysql_port \
                and source_server.database_name == target_server.database_name \
                and task_config.source_table_name == task_config.target_table_name:
            logger.warning("任务{}的源表和目标表相同，配置有误，请检查".format(task_config.task_name))
            return False
    return True


def archive_data(base_config: BaseConfig, task_config: TaskConfig):
    source_server = base_config.source_server
    target_server = base_config.target_server
    if target_server is not None:
        if source_server.mysql_host == target_server.mysql_host \
                and source_server.mysql_port == target_server.mysql_port \
                and source_server.database_name == target_server.database_name \
                and task_config.source_table_name == task_config.target_table_name:
            logger.warning("源表和目标表相同，配置有误，请检查")
            return
    print(task_config.task_type)
    mysql_archive = MyArchiver(
        source_mysql_server=source_server,
        source_table_name=task_config.source_table_name,
        data_condition=task_config.data_condition,
        batch_scan_rows=base_config.batch_scan_rows,
        batch_insert_rows=base_config.batch_insert_rows,
        batch_sleep_seconds=base_config.batch_sleep_seconds,
        max_query_seconds=base_config.max_query_seconds,
        max_primary_key=task_config.max_primary_key,
        min_primary_key=task_config.min_primary_key,
        task_type=task_config.task_type,
        target_mysql_server=target_server,
        target_table_name=task_config.target_table_name,
        etl_server=base_config.etl_server,
        etl_table_name=task_config.etl_table_name,
        is_dry_run=base_config.is_dry_run,
    )
    mysql_archive.loop_archive_data()


def main(command_args):
    logger.info("开始归档数据...")
    args = parse_args(command_args)
    logger.info("配置文件为：{}".format(args.config_file))
    config_name = os.path.split(args.config_file)[-1].lower().replace(".json", "").strip()
    LogHelper.init_logger(log_file_prefix=config_name)
    base_config = BaseConfig.get_base_config(config_file_path=args.config_file)
    for task_config in base_config.archive_tasks:
        try:
            logger.info("开始处理任务{}".format(task_config.task_name))
            if check_config(base_config=base_config, task_config=task_config):
                archive_data(base_config=base_config, task_config=task_config)
        except Exception as ex:
            logger.warning("归档任务{}执行失败,\n异常为：{},\n堆栈为：{}".format(
                task_config.task_name,
                str(ex),
                traceback.format_exc()
            ))
    logger.info("本轮归档结束")


if __name__ == '__main__':
    main(sys.argv[1:])
